home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Environments / PowerMacOberon feb96 / Debugger / RTDB.Mod (.txt) < prev    next >
Encoding:
Oberon Text  |  1995-08-07  |  10.3 KB  |  283 lines  |  [TEXT/.Ob4]

  1. Syntax10.Scn.Fnt
  2. StampElems
  3. Alloc
  4. 7 Aug 95
  5. InfoElems
  6. Alloc
  7. Syntax10.Scn.Fnt
  8. StampElems
  9. Alloc
  10. 7 Aug 95
  11. "Title": Run time debugger
  12. "Author": mah
  13. "Abstract": Control flow & Breakpoints
  14. "Keywords": 
  15. "Version": 
  16. "From":  25.10.94 16:53:38
  17. "Until": 
  18. "Changes": 
  19. ParcElems
  20. Alloc
  21. Syntax10i.Scn.Fnt
  22. Syntax10b.Scn.Fnt
  23. FoldElems
  24. Syntax10.Scn.Fnt
  25. Syntax10b.Scn.Fnt
  26. Syntax10i.Scn.Fnt
  27.         next-: ModuleInfo;
  28.         name-: ARRAY 32 OF CHAR; 
  29.         mod: Modules.Module;                        (* current mod-descriptor when steps written *)
  30.         steps: POINTER TO ARRAY OF LONGINT;    (* backup of overwritten instructions *)
  31.         mode: INTEGER;                                (* NormalMode, StepMode & BreakpointMode *)
  32.     END;
  33. Syntax10.Scn.Fnt
  34. Syntax10i.Scn.Fnt
  35. VAR mod: ModuleInfo; m: Modules.Module; stats: RTDC.Stat; adr, i: LONGINT;
  36. BEGIN
  37.     mod := modules;
  38.     WHILE mod # NIL DO 
  39.         m := SYS.VAL (Modules.Module, mod.mod);
  40.         IF (m.PC <= pc) & (pc < m.PC+m.codesize*4) THEN        (* module found *)
  41.             RTDC.Statements (mod.name, stats);
  42.             adr := m.PC;
  43.             FOR i := 0 TO LEN (stats.pc^)-1 DO
  44.                 adr := adr + 4*stats.pc[i];
  45.                 IF adr = pc THEN RETURN mod.steps[i] END
  46.             END;
  47.             RETURN RTDT.inop
  48.         END;
  49.         mod := mod.next
  50.     END;
  51.     RETURN RTDT.itw
  52. END InstrAtPC;
  53. Syntax10.Scn.Fnt
  54. VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
  55. BEGIN
  56.     m := Modules.ThisMod (mod.name);
  57.     RTDC.Statements (mod.name, stats);
  58.     IF stats.pc # NIL THEN
  59.         NEW (mod.steps, LEN (stats.pc^));
  60.         adr := m.PC;
  61.         FOR i := 0 TO LEN (stats.pc^)-1 DO
  62.             adr := adr + 4*stats.pc[i];
  63.             SYS.GET (adr, mod.steps[i])
  64.         END
  65. END GetBackupInstrs;
  66. Syntax10.Scn.Fnt
  67. VAR stats: RTDC.Stat; idx, adr, i: LONGINT; m: Modules.Module;
  68. BEGIN
  69.     IF mod.mode = NormalMode THEN RETURN END;
  70.     m := Modules.ThisMod (mod.name);
  71.     IF mod.mod = m THEN
  72.         RTDC.Statements (mod.name, stats); idx := LEN (stats.pc^);
  73.         IF stats.pc # NIL THEN
  74.             adr := m.PC; FOR  i := 0 TO idx-1 DO adr := adr + 4*stats.pc[i] END;
  75.             WHILE idx > 0 DO
  76.                 DEC (idx); SYS.PUT (adr, mod.steps[idx]);
  77.                 adr := adr - 4*stats.pc[idx]
  78.             END;
  79.             mod.mode := NormalMode
  80.         ELSE
  81.             Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
  82.             Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
  83.         END
  84.     ELSE
  85.         mod.steps := NIL
  86. END RestoreModule;
  87. Syntax10.Scn.Fnt
  88. VAR stats: RTDC.Stat; i, adr: LONGINT; m, d1: Modules.Module; d2, d3, startPC, endPC: LONGINT;
  89. BEGIN
  90.     m := Modules.ThisMod (mod.name);
  91.     IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
  92.     IF (mod.mode = StepOverMode) OR (mod.mode = StepMode) THEN RestoreModule (mod) END;
  93.     IF mod.mode = EntryMode THEN RETURN END;
  94.     IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
  95.     IF mod.steps # NIL THEN
  96.         RTDC.Statements (mod.name, stats);
  97.         adr := m.PC; endPC := 0;
  98.         FOR i := 0 TO LEN (stats.pc^)-1 DO
  99.             adr := adr + 4*stats.pc[i];
  100.             WHILE m.PC + endPC < adr DO
  101.                 RTDT.SearchProc (m.PC + endPC, d1, d2, d3, startPC, endPC); INC (startPC, m.PC)
  102.             END;
  103.             IF adr > startPC THEN
  104.                 SYS.PUT (adr, RTDT.itw);
  105.                 startPC := MAX (LONGINT)
  106.             END
  107.         END;
  108.         mod.mode := EntryMode
  109.     ELSE
  110.         Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
  111.         Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
  112. END EntryModule;
  113. Syntax10.Scn.Fnt
  114. VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
  115. BEGIN
  116.     m := Modules.ThisMod (mod.name);
  117.     IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
  118.     IF (mod.mode = StepOverMode) OR (mod.mode = EntryMode) THEN RestoreModule (mod) END;
  119.     IF mod.mode = StepMode THEN RETURN END;
  120.     IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
  121.     IF mod.steps # NIL THEN
  122.         RTDC.Statements (mod.name, stats);
  123.         adr := m.PC;
  124.         FOR i := 0 TO LEN (stats.pc^)-1 DO
  125.             adr := adr + 4*stats.pc[i];
  126.             SYS.PUT (adr, RTDT.itw)
  127.         END;
  128.         mod.mode := StepMode
  129.     ELSE
  130.         Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
  131.         Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
  132. END StepModule;
  133. Syntax10.Scn.Fnt
  134. VAR stats: RTDC.Stat; i, adr: LONGINT; m: Modules.Module;
  135. BEGIN
  136.     m := Modules.ThisMod (mod.name);
  137.     IF m # mod.mod THEN mod.mode := NormalMode; mod.steps := NIL; mod.mod := m END;
  138.     IF mod.steps = NIL THEN GetBackupInstrs (mod) END;
  139.     IF mod.steps # NIL THEN
  140.         RTDC.Statements (mod.name, stats);
  141.         adr := m.PC; beginPC := m.PC + beginPC; endPC := m.PC + endPC;
  142.         FOR i := 0 TO LEN (stats.pc^)-1 DO
  143.             adr := adr + 4*stats.pc[i];
  144.             IF (beginPC < adr) & (adr < endPC) THEN SYS.PUT (adr, RTDT.itw) END
  145.         END;
  146.         mod.mode := StepOverMode
  147.     ELSE
  148.         Texts.WriteString (w, mod.name); Texts.WriteString (w, " not compilable");
  149.         Texts.WriteLn (w); Texts.Append (Oberon.Log, w.buf)
  150. END StepOver;
  151. Syntax10.Scn.Fnt
  152. Syntax10i.Scn.Fnt
  153. (* set stepping in all modules *)
  154. VAR mod: ModuleInfo;
  155. BEGIN
  156.     mod := modules;
  157.     WHILE mod # NIL DO StepModule (mod); mod := mod.next END
  158. END StepAll;
  159. Syntax10.Scn.Fnt
  160. Syntax10i.Scn.Fnt
  161. (* Remove all step info and all breakpoints from all modules *)
  162. VAR mod: ModuleInfo;
  163. BEGIN
  164.     mod := modules;
  165.     WHILE mod # NIL DO RestoreModule (mod); mod := mod.next END
  166. END RestoreAll;
  167. Syntax10.Scn.Fnt
  168. Syntax10i.Scn.Fnt
  169. (* set breakpoints in all modules *)
  170. VAR m: GetBPMsg;
  171. BEGIN RestoreAll; Viewers.Broadcast (m)
  172. END BreakAll;
  173. Syntax10.Scn.Fnt
  174. Syntax10i.Scn.Fnt
  175. (* set breakpoints at all entry-points of all modules *)
  176. VAR mod: ModuleInfo;
  177. BEGIN
  178.     mod := modules;
  179.     WHILE mod # NIL DO EntryModule (mod); mod := mod.next END
  180. END EntryAll;
  181. Syntax10.Scn.Fnt
  182. Syntax10i.Scn.Fnt
  183. (* set step over for all procedures on stack *)
  184. VAR mod: ModuleInfo; p: RTDT.Proc;
  185. BEGIN
  186.     RestoreAll;
  187.     p := RTDT.procs;
  188.     WHILE p # NIL DO
  189.         mod := modules;
  190.         WHILE (mod # NIL) & (mod.name # p.modName) DO mod := mod.next END;
  191.         IF mod # NIL THEN StepOver (mod, p.beginPC, p.endPC) END;
  192.         p := p.up
  193. END StepOverAll;
  194. Syntax10.Scn.Fnt
  195. Syntax10i.Scn.Fnt
  196. (* release all debug info including list of debugged modules *)
  197. BEGIN RestoreAll; modules := NIL; RTDC.Release
  198. END CleanUp;
  199. Syntax10.Scn.Fnt
  200. Syntax10i.Scn.Fnt
  201. (* add modules to list of debugged modules *)
  202. VAR mod: ModuleInfo; 
  203. BEGIN
  204.     WHILE s.class = Texts.Name DO
  205.         mod := modules;
  206.         WHILE (mod # NIL) & (mod.name # s.s) DO mod := mod.next END;
  207.         IF mod = NIL THEN                            (* avoid debugging same module twice *)
  208.             NEW (mod); COPY (s.s, mod.name);
  209.             mod.next := modules; modules := mod
  210.         END;
  211.         Texts.Scan(s)
  212.     END;
  213. (*    EntryAll *)
  214. END AddModules;
  215. Syntax10.Scn.Fnt
  216. Syntax10i.Scn.Fnt
  217. (* return modulename & textposition corresponding to pc *)
  218. VAR m: Modules.Module; stats: RTDC.Stat; i, curpc: LONGINT;
  219. BEGIN
  220.     m := Modules.modules; 
  221.     WHILE (m # NIL) & ((pc < m.PC) OR (m.PC+4*m.codesize < pc)) DO m := m.link END;
  222.     COPY (m.name, name); pc := (pc-m.PC) DIV 4;
  223.     RTDC.Statements (name, stats); i := 0; curpc := stats.pc[0];
  224.     WHILE (i < LEN (stats.pc^)-1) & (pc > curpc) DO INC (i); curpc := curpc+stats.pc[i] END;
  225.     pos :=  stats.pos[i]
  226. END PCToPos;
  227. Syntax10.Scn.Fnt
  228. Syntax10i.Scn.Fnt
  229. (* return pc relative to module 'name' corrsponding to textposition 'pos' *)
  230. VAR stats: RTDC.Stat; bestpos, curpc, i: LONGINT;
  231. BEGIN
  232.     RTDC.Statements (name, stats);
  233.     bestpos := stats.pos[0]; curpc := stats.pc[0]; pc := curpc;
  234.     FOR i:=1 TO LEN (stats.pc^)-1 DO 
  235.         curpc := curpc + stats.pc[i];    
  236.         IF (stats.pos[i] <= pos) & (stats.pos[i] > bestpos) THEN
  237.             bestpos := stats.pos[i]; pc := curpc
  238.         END
  239.     END;
  240.     pc := 4*pc
  241. END PosToPC;
  242. Syntax10.Scn.Fnt
  243. Syntax10i.Scn.Fnt
  244. VAR mod: ModuleInfo; pc: LONGINT;
  245. BEGIN
  246.     mod := modules;
  247.     WHILE (mod # NIL) & (mod.name # name) DO mod := mod.next END;
  248.     IF mod = NIL THEN RETURN FALSE END;            (* Illegal breakpoint *)
  249.     PosToPC (name, pos, pc);
  250.     StepOver (mod, pc - 4, pc + 4);
  251.     RETURN TRUE
  252. END BreakAtPC;
  253. MODULE RTDB; (* Run time debugger: Breakpoints & control flow; mah 25.10.94 (
  254. IMPORT RTDC, RTDT, Modules, SYS := SYSTEM, Texts, Oberon, Viewers, Display;
  255. CONST
  256.     NormalMode = 0;                (* debug modes for a module *)
  257.     StepMode = 1;
  258.     StepOverMode = 2;
  259.     EntryMode = 3;
  260.     ModuleInfo- = POINTER TO ModuleInfoDesc;
  261.     ModuleInfoDesc- = RECORD
  262.     GetBPMsg* = RECORD (Display.FrameMsg) END;        (* sent to collect breakpoints *)
  263.     modules-: ModuleInfo; 
  264.     w: Texts.Writer;
  265. PROCEDURE InstrAtPC (pc: LONGINT) : LONGINT;
  266. PROCEDURE GetBackupInstrs (mod: ModuleInfo);
  267. PROCEDURE RestoreModule (mod: ModuleInfo);
  268. PROCEDURE EntryModule (mod: ModuleInfo);
  269. PROCEDURE StepModule (mod: ModuleInfo);
  270. PROCEDURE StepOver (mod: ModuleInfo; beginPC, endPC: LONGINT);
  271. PROCEDURE StepAll*;
  272. PROCEDURE RestoreAll*;
  273. PROCEDURE BreakAll*;
  274. PROCEDURE EntryAll*;
  275. PROCEDURE StepOverAll*;
  276. PROCEDURE CleanUp*;
  277. PROCEDURE AddModules* (s: Texts.Scanner);
  278. PROCEDURE PCToPos* (pc: LONGINT; VAR name: ARRAY OF CHAR; VAR pos: LONGINT);
  279. PROCEDURE PosToPC* (VAR name: ARRAY OF CHAR; pos: LONGINT; VAR pc: LONGINT);
  280. PROCEDURE BreakAtPC* (VAR name: ARRAY OF CHAR; pos: LONGINT) : BOOLEAN;
  281. BEGIN Texts.OpenWriter (w); RTDT.LatestTrapInstr := InstrAtPC
  282. END RTDB.
  283.